package com.vrv.vap.baseline.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ZipUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Date;

@Component
public class FileOperationUtil {
    private static final Logger log = LoggerFactory.getLogger(FileOperationUtil.class);

    @Value("${form.data.base-path:${user.dir}/form_data}")
    private String formDataDir;

    @Value("${form.data.download-path:${form.data.base-path}/download}")
    private String downloadPath;

    public String createDownloadDir() {
        File formDataDirectory = new File(downloadPath);
        if (!formDataDirectory.exists()) {
            formDataDirectory.mkdirs();
        }
        return downloadPath;
    }

    public String createChildDir(String key, String format) {
        String fileName = key + "-" + format;
        String targetDir = createDownloadDir() + File.separator + fileName;
        FileUtil.mkdir(targetDir);
        return targetDir;
    }

    public File createFile(String fname, String key, String format) throws IOException {
        String childDir = this.createChildDir(key, format);
        File file = new File(childDir + File.separator + fname);
        if (!file.exists()) {
            file.createNewFile();
        }
        return file.getAbsoluteFile();
    }

    public void writeContentToFile(File file, String content) throws IOException {
        try (FileWriter writer = new FileWriter(file)) {
            writer.write(content);
        } catch (IOException e) {
            log.error("Failed to write content to file: {}", file.getAbsolutePath(), e);
            throw e;
        }
    }

    public void writeBytesToFile(File file, byte[] bytes) throws IOException {
        try (FileOutputStream outputStream = new FileOutputStream(file)) {
            outputStream.write(bytes);
            outputStream.flush();
            log.info("Successfully wrote bytes to file: {}", file.getAbsolutePath());
        } catch (IOException e) {
            log.error("Failed to write bytes to file: {}", file.getAbsolutePath(), e);
            throw e;
        }
    }

    public String createZipFile(String sourceDir) {
        String zipFileName = sourceDir + ".zip";
        File zipFile = new File(zipFileName);
        if (zipFile.exists()) {
            FileUtil.del(zipFile);
        }
        ZipUtil.zip(sourceDir, zipFileName, false);
        return zipFileName;
    }

    public String getCurrentTimeFormat() {
        return DateUtil.format(new Date(), "yyyyMMddHHmmss");
    }

    public void cleanupOldFiles(int retentionDays) {
        String downloadDir = createDownloadDir();
        File directory = new File(downloadDir);
        if (directory.exists() && directory.isDirectory()) {
            File[] files = directory.listFiles();
            if (files != null) {
                long cutoffTime = System.currentTimeMillis() - (retentionDays * 24L * 60L * 60L * 1000L);
                for (File file : files) {
                    if (file.lastModified() < cutoffTime) {
                        FileUtil.del(file);
                        log.info("Deleted old file: {}", file.getAbsolutePath());
                    }
                }
            }
        }
    }

    public void writeFileToResponse(String filePath, HttpServletResponse response) throws IOException {
        File file = new File(filePath);
        if (!file.exists()) {
            log.error("File not found: {}", filePath);
            throw new FileNotFoundException("File not found: " + filePath);
        }

        if (!file.canRead()) {
            log.error("File is not readable: {}", filePath);
            throw new IOException("File is not readable: " + filePath);
        }

        try (FileInputStream fileInputStream = new FileInputStream(file);
             OutputStream outputStream = response.getOutputStream()) {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, bytesRead);
            }
            outputStream.flush();
            log.info("Successfully wrote file to response: {}", filePath);
        } catch (IOException e) {
            log.error("Error writing file to response: {}", filePath, e);
            throw new IOException("Error writing file to response: " + e.getMessage(), e);
        }
    }

    public void deleteDirectory(File directory) throws IOException {
        if (!directory.exists()) {
            return;
        }

        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    if (!file.delete()) {
                        throw new IOException("Failed to delete file: " + file.getAbsolutePath());
                    }
                }
            }
        }

        if (!directory.delete()) {
            throw new IOException("Failed to delete directory: " + directory.getAbsolutePath());
        }
    }
}